using AutoMapper;
using B.S.NewMedical.Api.Write.Application.Command.ContentManagement.Patient;
using B.S.NewMedical.Domain.Hospital;
using B.S.NewMedical.Domain.Appointment;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace B.S.NewMedical.Api.Write.Application.Handler.ContentManagement.Patient
{
    /// <summary>
    /// 新增患者命令处理器
    /// </summary>
    public class AddPatientCommandHandler : IRequestHandler<AddPatientCommand, int>
    {
        private readonly IMapper _mapper;
        private readonly IBaseRepository<PatientModel> _patientRepository;
        private readonly IBaseRepository<MedicalCard> _medicalCardRepository;

        public AddPatientCommandHandler(
            IMapper mapper, 
            IBaseRepository<PatientModel> patientRepository,
            IBaseRepository<MedicalCard> medicalCardRepository)
        {
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
            _patientRepository = patientRepository ?? throw new ArgumentNullException(nameof(patientRepository));
            _medicalCardRepository = medicalCardRepository ?? throw new ArgumentNullException(nameof(medicalCardRepository));
        }

        /// <summary>
        /// 处理新增患者命令
        /// </summary>
        /// <param name="request">新增患者命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>新增的患者ID</returns>
        public async Task<int> Handle(AddPatientCommand request, CancellationToken cancellationToken)
        {
            // 验证出生日期是否合理
            if (request.DateOfBirth > DateTime.Now)
            {
                throw new ArgumentException("出生日期不能晚于当前日期");
            }

            if (request.DateOfBirth < DateTime.Now.AddYears(-150))
            {
                throw new ArgumentException("出生日期不能早于150年前");
            }

            // 检查身份证号是否重复
            var existingPatientByIDCard = _patientRepository.GetAll()
                .Where(p => p.IDCard == request.IDCard && !p.IsDeleted)
                .FirstOrDefault();

            if (existingPatientByIDCard != null)
            {
                throw new ArgumentException($"身份证号 '{request.IDCard}' 已存在");
            }

            // 检查联系方式是否重复（可选验证，根据业务需求决定）
            var existingPatientByContact = _patientRepository.GetAll()
                .Where(p => p.ContactInfo == request.ContactInfo && !p.IsDeleted)
                .FirstOrDefault();

            if (existingPatientByContact != null)
            {
                throw new ArgumentException($"联系方式 '{request.ContactInfo}' 已被其他患者使用");
            }

            // 如果提供了AccountId，验证其是否有效（这里简单检查不为0）
            if (request.AccountId.HasValue && request.AccountId.Value <= 0)
            {
                throw new ArgumentException("用户ID必须大于0");
            }

            // 使用 AutoMapper 将命令映射为实体
            var patientEntity = _mapper.Map<PatientModel>(request);

            // 设置创建时间
            patientEntity.CreateTime = DateTime.Now;

            // 调用仓储层保存患者数据
            await _patientRepository.CreateAsync(patientEntity);

            // 生成唯一就诊卡号
            var cardNo = await GenerateUniqueCardNumber();

            // 创建医疗卡记录
            var medicalCard = new MedicalCard
            {
                Card_no = cardNo,
                Card_price = 0, // 初始卡余额为0
                Patient_id = patientEntity.Id,
                Issue_date = DateTime.Now,
                Status = "正常"
            };

            // 保存医疗卡
            await _medicalCardRepository.CreateAsync(medicalCard);

            return patientEntity.Id;
        }

        /// <summary>
        /// 生成唯一的就诊卡号（日期+6位流水）
        /// </summary>
        /// <returns>唯一卡号</returns>
        private async Task<string> GenerateUniqueCardNumber()
        {
            var today = DateTime.Today.ToString("yyyyMMdd");
            string cardNo;
            int attempts = 0;
            const int maxAttempts = 100; // 防止无限循环

            do
            {
                attempts++;
                if (attempts > maxAttempts)
                {
                    throw new InvalidOperationException("无法生成唯一的就诊卡号，请稍后重试");
                }

                // 查询当天已生成的卡号数量
                var todayCardCount = await _medicalCardRepository.GetAll()
                    .Where(c => c.Card_no.StartsWith(today) && !c.IsDeleted)
                    .CountAsync();

                // 生成新的序号（从1开始）
                var sequence = todayCardCount + 1;
                cardNo = $"{today}{sequence:D6}"; // D6表示6位数字，不足补0

                // 检查是否已存在
                var exists = await _medicalCardRepository.GetAll()
                    .AnyAsync(c => c.Card_no == cardNo && !c.IsDeleted);

                if (!exists)
                {
                    break;
                }
            } while (true);

            return cardNo;
        }
    }
}